#!/usr/bin/env python

from __future__ import print_function

from hashlib import md5
from os.path import isfile
from collections import OrderedDict
import sys
import zipfile
import xml.etree.ElementTree as elementTree

systems = {

    # Atari
    "atari5200": {"name": "Atari 5200", "biosFiles": [{"md5": "281f20ea4320404ec820fb7ec0693b38", "file": "bios/5200.rom"}]},

    "atari800":  {"name": "Atari 800", "biosFiles":  [{"md5": "06daac977823773a3eea3422fd26a703", "file": "bios/ATARIXL.ROM"},
                                                      {"md5": "0bac0c6a50104045d902df4503a4c30b", "file": "bios/ATARIBAS.ROM"},
                                                      {"md5": "eb1f32f5d9f382db1bbfb8d7f9cb343a", "file": "bios/ATARIOSA.ROM"},
                                                      {"md5": "a3e8d617c95d08031fe1b20d541434b2", "file": "bios/ATARIOSB.ROM"}]},

    "atari7800": {"name": "Atari 7800", "biosFiles": [{"md5": "0763f1ffb006ddbe32e52d497ee848ae", "file": "bios/7800 BIOS (U).rom"}]},

    "atarist":   {"name": "Atari ST", "biosFiles":   [{"md5": "b2a8570de2e850c5acf81cb80512d9f6", "file": "bios/tos.img"}]},

    "atarilynx": {"name": "Lynx", "biosFiles":       [{"md5": "fcd403db69f54290b51035d82f835e7b", "file": "bios/lynxboot.img"}]},


    # Colecovision
    "colecovision": {"name": "Colecovision", "biosFiles": [{"md5": "", "file": "bios/Machines/COL - Bit Corporation Dina/config.ini"},
                                                           {"md5": "1de922acdd742d31349c2801e9768c35", "file": "bios/Machines/COL - Bit Corporation Dina/czz50-1.rom"},
                                                           {"md5": "72b089dc55b7fe7ffb5028f365e8c045", "file": "bios/Machines/COL - Bit Corporation Dina/czz50-2.rom"},
                                                           {"md5": "2c66f5911e5b42b8ebe113403548eee7", "file": "bios/Machines/COL - ColecoVision/coleco.rom"},
                                                           {"md5": "", "file": "bios/Machines/COL - ColecoVision/config.ini"},
                                                           {"md5": "2c66f5911e5b42b8ebe113403548eee7", "file": "bios/Machines/COL - ColecoVision with Opcode Memory Extension/coleco.rom"},
                                                           {"md5": "", "file": "bios/Machines/COL - ColecoVision with Opcode Memory Extension/config.ini"},
                                                           {"md5": "", "file": "bios/Machines/COL - Spectravideo SVI-603 Coleco/config.ini"},
                                                           {"md5": "c60a2e85572c0ccb69505a7646d5c1b6", "file": "bios/Machines/COL - Spectravideo SVI-603 Coleco/SVI603.ROM"},
                                                           {"md5": "", "file": "bios/Databases/colecodb.xml"},
                                                           {"md5": "2c66f5911e5b42b8ebe113403548eee7", "file": "bios/colecovision.rom"},
                                                           {"md5": "2c66f5911e5b42b8ebe113403548eee7", "file": "bios/BIOS.col"}]},


    # Commodore
    "amiga": {"name": "Amiga/CD32", "biosFiles": [{"md5": "89da1838a24460e4b93f4f0c5d92d48d", "file": "bios/CDTV Extended-ROM v1.0 (1991)(Commodore)(CDTV)[!].rom"},
                                                  {"md5": "85ad74194e87c08904327de1a9443b7a", "file": "bios/Kickstart v1.2 r33.180 (1986)(Commodore)(A500-A1000-A2000)[!].rom"},
                                                  {"md5": "68c9c0826f6c0ca20546d588ee77391c", "file": "bios/Kickstart v1.2 rev 33.166 (1986)(Commodore)(A1000).rom"},
                                                  {"md5": "192d6d950d0ed3df8040b788502831c2", "file": "bios/Kickstart v1.3 r34.5 (1987)(Commodore)(A500-A1000-A2000-CDTV)[o].rom"},
                                                  {"md5": "82a21c1890cae844b3df741f2762d48d", "file": "bios/Kickstart v1.3 r34.5 (1987)(Commodore)(A500-A1000-A2000-CDTV)[!].rom"},
                                                  {"md5": "dc10d7bdd1b6f450773dfb558477c230", "file": "bios/Kickstart v2.04 r37.175 (1991)(Commodore)(A500+)[!].rom"},
                                                  {"md5": "465646c9b6729f77eea5314d1f057951", "file": "bios/Kickstart v2.05 r37.350 (1992)(Commodore)(A600HD)[!].rom"},
                                                  {"md5": "5f8924d013dd57a89cf349f4cdedc6b1", "file": "bios/Kickstart v3.1 r40.60 (1993)(Commodore)(CD32).rom"},
                                                  {"md5": "646773759326fbac3b2311fd8c8793ee", "file": "bios/Kickstart v3.1 r40.68 (1993)(Commodore)(A1200)[!].rom"},
                                                  {"md5": "413590e50098a056cfec418d3df0212d", "file": "bios/Kickstart v3.1 r40.68 (1993)(Commodore)(A3000).rom"},
                                                  {"md5": "9bdedde6a4f33555b4a270c8ca53297d", "file": "bios/Kickstart v3.1 r40.68 (1993)(Commodore)(A4000).rom"},
                                                  {"md5": "85ad74194e87c08904327de1a9443b7a", "file": "bios/kick33180.A500"},
                                                  {"md5": "82a21c1890cae844b3df741f2762d48d", "file": "bios/kick34005.A500"},
                                                  {"md5": "dc10d7bdd1b6f450773dfb558477c230", "file": "bios/kick37175.A500"},
                                                  {"md5": "5f8924d013dd57a89cf349f4cdedc6b1", "file": "bios/kick40060.CD32"},
                                                  {"md5": "bb72565701b1b6faece07d68ea5da639", "file": "bios/kick40060.CD32.ext"},
                                                  {"md5": "e40a5dfb3d017ba8779faba30cbd1c8e", "file": "bios/kick40063.A600"},
                                                  {"md5": "646773759326fbac3b2311fd8c8793ee", "file": "bios/kick40068.A1200"},
                                                  {"md5": "9bdedde6a4f33555b4a270c8ca53297d", "file": "bios/kick40068.A4000"},
                                                  {"md5": "bb72565701b1b6faece07d68ea5da639", "file": "bios/CD32 Extended-ROM r40.60 (1993)(Commodore)(CD32).rom"}]},


    # Magnavox and Philips
    "o2em": {"name": "Odyssey 2", "biosFiles": [{"md5": "562d5ebf9e030a40d6fabfc2f33139fd", "file": "bios/o2rom.bin"},
                                                {"md5": "f1071cdb0b6b10dde94d3bc8a6146387", "file": "bios/c52.bin"},
                                                {"md5": "c500ff71236068e0dc0d0603d265ae76", "file": "bios/g7400.bin"},
                                                {"md5": "279008e4a0db2dc5f1c048853b033828", "file": "bios/jopac.bin"}]},


    # Mattel
    "intellivision": {"name": "Mattel Intellivision", "biosFiles": [{"md5": "62e761035cb657903761800f4437b8af", "file": "bios/exec.bin"},
                                                                    {"md5": "0cd5946c6473e42e8e4c2137785e427f", "file": "bios/grom.bin"},
                                                                    {"md5": "2e72a9a2b897d330a35c8b07a6146c52", "file": "bios/ECS.bin"},
                                                                    {"md5": "d5530f74681ec6e0f282dab42e6b1c5f", "file": "bios/IVOICE.bin"}]},


    # Microsoft
    "msx": {"name": "MSX", "biosFiles": [{"md5": "", "file": "bios/Machines/Forte II Games - Pesadelo/config.ini"},
                                         {"md5": "", "file": "bios/Machines/Forte II Games - Pesadelo/pesadelo.rom"},
                                         {"md5": "", "file": "bios/Machines/MSX/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX/MSX.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX/MSX2.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX/MSX2EXT.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX/MSX2P.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX/MSX2PEXT.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX/MSXDOS2.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX - Al Alamiah AX-170/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Arabic/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Brazilian/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Brazilian/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX - C-BIOS/cbios.txt"},
                                         {"md5": "", "file": "bios/Machines/MSX - C-BIOS/cbios_logo_msx1.rom"},
                                         {"md5": "", "file": "bios/Machines/MSX - C-BIOS/cbios_main_msx1.rom"},
                                         {"md5": "", "file": "bios/Machines/MSX - C-BIOS/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Canon V-10/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Canon V-20/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Daewoo DPC-100/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Daewoo DPC-180/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Daewoo DPC-200/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Estonian/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Frael Bruc 100-1/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - French/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - German/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - German/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX - Goldstar FC-200/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Gradiente Expert 1.0/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Gradiente Expert 1.1/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Gradiente Expert 1.3/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Gradiente Expert DDPlus/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Gradiente Expert Plus/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Japanese/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Japanese/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX - JVC HC-7GB/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Korean/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Korean/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX - Mitsubishi ML-F80/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Mitsubishi ML-FX1/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - National CF-1200/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Panasonic FS-A1/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Panasonic FS-A1 (a)/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Panasonic FS-A1F/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Panasonic FS-A1FM/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Panasonic FS-A1MK2/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8220/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8220 (a)/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8245/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8245F/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8250/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8255/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8280/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Philips NMS-8280G/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Philips VG-8230/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Philips VG-8235/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sharp Epcom HotBit 1.2/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sharp Epcom HotBit 1.3b/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sharp Epcom HotBit 1.3p/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sony HB-10P/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sony HB-201/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sony HB-201P/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sony HB-20P/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sony HB-501P/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sony HB-55D/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sony HB-55P/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sony HB-75D/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sony HB-75P/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Spanish/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Spectravideo SVI-728/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Spectravideo SVI-738/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Spectravideo SVI-738-2 CUC/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Spectravideo SVI-738-2 JP Grobler/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Spectravideo SVI-738-2 LC Grosso/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Swedish/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Talent TPC-310/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Toshiba HX-23/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Toshiba HX-23F/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Virtual Haesung Console/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Yamaha CX7M/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Yamaha CX7M-128/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX2+/MSX.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX2+/MSX2.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX2+/MSX2EXT.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX2+/MSX2P.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX2+/MSX2PEXT.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX2+/MSXDOS2.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - Brazilian/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - C-BIOS/cbios.txt"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - C-BIOS/cbios_logo_msx2+.rom"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - C-BIOS/cbios_main_msx2+.rom"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - C-BIOS/cbios_music.rom"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - C-BIOS/cbios_sub.rom"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - C-BIOS/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - Ciel Expert 3 IDE/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - Ciel Expert 3 Turbo/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Spectravideo SVI-738 Swedish/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Swedish/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Swedish/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX - Talent DPC-200/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Talent DPC-200A/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Toshiba HX-10/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Toshiba HX-10S/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Toshiba HX-20/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Yamaha CX5M-1/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Yamaha CX5M-128/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Yamaha CX5M-2/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Yamaha CX5MII/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Yamaha YIS303/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Yamaha YIS503/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Yamaha YIS503F/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Yamaha YIS503II/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Yamaha YIS503IIR/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Yamaha YIS503M/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Yashica YC-64/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Yeno DPC-64/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Yeno MX64/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX2/MSX.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX2/MSX2.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX2/MSX2EXT.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX2/MSX2P.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX2/MSX2PEXT.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX2/MSXDOS2.ROM"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Al Alamiah AX-350/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Al Alamiah AX-370/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Arabic/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Arabic/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Brazilian/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Brazilian/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - C-BIOS/cbios.txt"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - C-BIOS/cbios_logo_msx2.rom"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - C-BIOS/cbios_main_msx2.rom"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - C-BIOS/cbios_sub.rom"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - C-BIOS/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Daewoo CPC-300/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Daewoo CPC-300E/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Daewoo CPC-400/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Daewoo CPC-400S/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Estonian/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - French/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - French/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - German/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - German/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Gradiente Expert 2.0/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Japanese/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Japanese/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Korean/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Korean/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - National FS-4500/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - National FS-4600/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - National FS-4700/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - National FS-5000/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - National FS-5500F1/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - National FS-5500F2/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Daewoo DPC-200E/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - National CF-2000/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sharp Epcom HotBit 1.1/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Spectravideo SVI-738 Henrik Gilvad/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Yamaha YIS503IIR Estonian/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Only PSG/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Only PSG/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Philips VG-8235F/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Spanish/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Spanish/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - European/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - National CF-2700/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - National CF-3000/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - National CF-3300/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - National FS-1300/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - National FS-4000/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Olympia PHC-2/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Olympia PHC-28/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Panasonic CF-2700G/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Philips NMS-801/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Philips VG-8000/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Philips VG-8010/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Philips VG-8010F/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Philips VG-8020-00/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Philips VG-8020-20/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Philips VG-8020F/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Pioneer PX-7/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Pioneer PX-V60/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Russian/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sanyo MPC-100/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sanyo MPC-64/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sanyo PHC-28L/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sanyo PHC-28S/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX - Sanyo Wavy MPC-10/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - Gradiente Expert AC88+/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - Gradiente Expert DDX+/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - MSXPLAYer 2003/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - Panasonic FS-A1FX/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - Panasonic FS-A1WSX/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - Panasonic FS-A1WX/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - Panasonic FS-A1WX (a)/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - Sanyo Wavy PHC-35J/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - Sanyo Wavy PHC-70FD1/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - Sanyo Wavy PHC-70FD2/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - Sony HB-F1XDJ/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - Sony HB-F1XV/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2+ - Sony HB-F9S+/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSXturboR/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSXturboR - European/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSXturboR - Panasonic FS-A1GT/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSXturboR - Panasonic FS-A1ST/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSXturboR - Panasonic FS-A1ST (a)/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSXturboR - Panasonic FS-A1ST (b)/config.ini"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2G.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXDOS23.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/ARAB1.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/ARABIC.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/BEERIDE.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/FMPAC.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/GCVMX80.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/HANGUL.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/KANJI.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MICROSOLDISK.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MOONSOUND.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2AR.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2AREXT.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2BR.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2BREXT.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2EXT.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2FR.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2FREXT.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2GEXT.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2HAN.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2J.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2JEXT.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2KR.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2KREXT.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2P.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2PEXT.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2PMUS.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2R.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2R2.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2REXT.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2SE.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2SP.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSX2SPEXT.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXAR.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXBR.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXDOS2.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXFR.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXG.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXHAN.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXJ.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXKANJI.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXKR.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXR.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXR2.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXSE.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXSP.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXTR.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXTREXT.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXTRMUS.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/MSXTROPT.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/NATIONALDISK.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/NOVAXIS.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/nowindDos1.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/nowindDos2.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/PAINT.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/PANASONICDISK.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/PHILIPSDISK.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/RS232.ROM"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/Shared.txt"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/SUNRISEIDE.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/SWP.rom"},
                                         {"md5": "", "file": "bios/Machines/Shared Roms/XBASIC2.rom"},
                                         {"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-318/config.ini"},
                                         {"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-318/svi318.rom"},
                                         {"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328/config.ini"},
                                         {"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328/svi328.rom"},
                                         {"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 80 Column/config.ini"},
                                         {"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 80 Column/svi328a.rom"},
                                         {"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 80 Column/svi806.rom"},
                                         {"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 80 Swedish/config.ini"},
                                         {"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 80 Swedish/svi328a.rom"},
                                         {"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 80 Swedish/svi806se.rom"},
                                         {"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 MK2/config.ini"},
                                         {"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 MK2/svi328a.rom"},
                                         {"md5": "", "file": "bios/Machines/SVI - Spectravideo SVI-328 MK2/svi806.rom"},
                                         {"md5": "", "file": "bios/Machines/Turbo-R/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Philips VG-8240/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Russian/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Russian/hardwareconfig.xml"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sanyo Wavy MPC-25FD/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sanyo Wavy PHC-23/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sharp Epcom HotBit 2.0/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F1/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F1II/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F1XD/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F1XDMK2/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F500/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F500P/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F700D/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F700F/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F700P/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F700S/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F900/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F900 (a)/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F9P/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F9P Russian/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-F9S/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-G900AP/config.ini"},
                                         {"md5": "", "file": "bios/Machines/MSX2 - Sony HB-G900P/config.ini"}]},


    # NEC
    "pcengine":   {"name": "PC Engine", "biosFiles":  [{"md5": "38179df8f4ac870017db21ebcbf53114", "file": "bios/syscard3.pce"}]},

    "pcfx":       {"name": "PC-FX", "biosFiles":      [{"md5": "08e36edbea28a017f79f8d4f7ff9b6d7", "file": "bios/pcfx.rom"}]},

    "supergrafx": {"name": "Supergrafx", "biosFiles": [{"md5": "38179df8f4ac870017db21ebcbf53114", "file": "bios/syscard3.pce"},
                                                       {"md5": "", "file": "bios/syscard2.pce"},
                                                       {"md5": "", "file": "bios/syscard1.pce"},
                                                       {"md5": "", "file": "bios/gexpress.pce"}]},

    "pc88": {"name": "NEC - PC-8800", "biosFiles": [{"md5": "", "file": "bios/quasi88/DISK.ROM"},
                                                              {"md5": "", "file": "bios/quasi88/N88.ROM"},
                                                              {"md5": "", "file": "bios/quasi88/N88N.ROM"},
                                                              {"md5": "", "file": "bios/quasi88/N88_0.ROM"},
                                                              {"md5": "", "file": "bios/quasi88/N88_1.ROM"},
                                                              {"md5": "", "file": "bios/quasi88/N88_2.ROM"},
                                                              {"md5": "", "file": "bios/quasi88/N88_3.ROM"},
                                                              {"md5": "", "file": "bios/quasi88/N88_KNJ1.ROM"},
                                                              {"md5": "", "file": "bios/quasi88/N88_KNJ2.ROM"}]},

    # Nintendo
    "fds":         {"name": "Nintendo Family Computer Disk System", "biosFiles": [{"md5": "", "file": "bios/NstDatabase.xml"},
                                                                                  {"md5": "ca30b50f880eb660a320674ed365ef7a", "file": "bios/disksys.rom"}]},

    "gb":          {"name": "Game Boy", "biosFiles":                             [{"md5": "32fbbd84168d3482956eb3c5051637f5", "file": "bios/gb_bios.bin"},
                                                                                  {"md5": "dbfce9db9deaa2567f6a84fde55f9680", "file": "bios/gbc_bios.bin"}]},

    "gbc":         {"name": "Game Boy Color", "biosFiles":                       [{"md5": "32fbbd84168d3482956eb3c5051637f5", "file": "bios/gb_bios.bin"},
                                                                                  {"md5": "dbfce9db9deaa2567f6a84fde55f9680", "file": "bios/gbc_bios.bin"}]},

    "gba":         {"name": "Game Boy Advance", "biosFiles":                     [{"md5": "a860e8c0b6d573d191e4ec7db1b1e4f6", "file": "bios/gba_bios.bin"},
                                                                                  {"md5": "32fbbd84168d3482956eb3c5051637f5", "file": "bios/gb_bios.bin"},
                                                                                  {"md5": "dbfce9db9deaa2567f6a84fde55f9680", "file": "bios/gbc_bios.bin"},
                                                                                  {"md5": "d574d4f9c12f305074798f54c091a8b4", "file": "bios/sgb_bios.bin"}]},

    "n64":         {"name": "Nintendo 64", "biosFiles":                          [{"md5": "8d3d9f294b6e174bc7b1d2fd1c727530", "file": "bios/64DD_IPL.bin"}]},

    "nds":         {"name": "Nintendo DS", "biosFiles":                          [{"md5": "145eaef5bd3037cbc247c213bb3da1b3", "file": "bios/firmware.bin"},
                                                                                  {"md5": "df692a80a5b1bc90728bc3dfc76cd948", "file": "bios/bios7.bin"},
                                                                                  {"md5": "a392174eb3e572fed6447e956bde4b25", "file": "bios/bios9.bin"}]},

    "satellaview": {"name": "Satellaview", "biosFiles":                          [{"md5": "96cf17bf589fcbfa6f8de2dc84f19fa2", "file": "bios/BS-X.bin"}]},

    "sufami":      {"name": "Sufami", "biosFiles":                               [{"md5": "d3a44ba7d42a74d3ac58cb9c14c6a5ca", "file": "bios/STBIOS.bin"}]},


    # Panasonic, Sanyo and Goldstar
    "3do": {"name": "3DO", "biosFiles": [{"md5": "f47264dd47fe30f73ab3c010015c155b", "file": "bios/panafz1.bin"},
                                         {"md5": "51f2f43ae2f3508a14d9f56597e2d3ce", "file": "bios/panafz10.bin"},
                                         {"md5": "8639fd5e549bd6238cfee79e3e749114", "file": "bios/goldstar.bin"},
                                         {"md5": "35fa1a1ebaaeea286dc5cd15487c13ea", "file": "bios/sanyotry.bin"},
                                         {"md5": "8970fc987ab89a7f64da9f8a8c4333ff", "file": "bios/3do_arcade_saot.bin"}]},


    # Sega
    "naomi":        {"name": "Naomi", "biosFiles":        [{"md5": "3bffafac42a7767d8dcecf771f5552ba", "file": "bios/dc/naomi_boot.bin"},
                                                           {"md5": "e63d892cdb8b532351dc7020bb60b6f4", "file": "bios/dc/naomi.zip"}]},

    "atomiswave":   {"name": "Atomiswave", "biosFiles":   [{"md5": "0ec5ae5b5a5c4959fa8b43fcf8687f7c", "file": "bios/dc/awbios.zip"}]},

    "dreamcast":    {"name": "Dreamcast", "biosFiles":    [{"md5": "e10c53c2f8b90bab96ead2d368858623", "file": "bios/dc/dc_boot.bin"},
                                                           {"md5": "0a93f7940c455905bea6e392dfde92a4", "file": "bios/dc/dc_flash.bin"}]},

    "gamegear":     {"name": "Game Gear", "biosFiles":    [{"md5": "672e104c3be3a238301aceffc3b23fd6", "file": "bios/bios.gg"}]},

    "mastersystem": {"name": "MasterSystem", "biosFiles": [{"md5": "840481177270d5642a14ca71ee72844c", "file": "bios/bios_E.sms"},
                                                           {"md5": "840481177270d5642a14ca71ee72844c", "file": "bios/bios_U.sms"},
                                                           {"md5": "24a519c53f67b00640d0048ef7089105", "file": "bios/bios_J.sms"}]},

    "saturn":       {"name": "Sega Saturn", "biosFiles":  [{"md5": "af5828fdff51384f99b3c4926be27762", "file": "bios/saturn_bios.bin"},
                                                           {"md5": "85ec9ca47d8f6807718151cbcca8b964", "file": "bios/sega_101.bin"},
                                                           {"md5": "3240872c70984b6cbfda1586cab68dbe", "file": "bios/mpr-17933.bin"},
                                                           {"md5": "255113ba943c92a54facd25a10fd780c", "file": "bios/mpr-18811-mx.ic1"},
                                                           {"md5": "1cd19988d1d72a3e7caa0b73234c96b4", "file": "bios/mpr-19367-mx.ic1"},
                                                           {"md5": "53a094ad3a188f86de4e64624fe9b3ca", "file": "bios/stvbios.zip"}]},

    "segacd":       {"name": "Sega CD", "biosFiles":      [{"md5": "e66fa1dc5820d254611fdcdba0662372", "file": "bios/bios_CD_E.bin"},
                                                           {"md5": "854b9150240a198070150e4566ae1290", "file": "bios/bios_CD_U.bin"},
                                                           {"md5": "278a9397d192149e84e820ac621a8edd", "file": "bios/bios_CD_J.bin"}]},

    "sc-3000":      {"name": "SC-3000", "biosFiles":      [{"md5": "", "file": "bios/Machines/SEGA - SC-3000/config.ini"}]},


    # Sharp
    "x68000": {"name": "Sharp x68000", "biosFiles": [{"md5": "", "file": "bios/keropi/iplrom.dat"},
                                                     {"md5": "", "file": "bios/keropi/iplrom30.dat"},
                                                     {"md5": "", "file": "bios/keropi/iplromco.dat"},
                                                     {"md5": "", "file": "bios/keropi/iplromxv.dat"},
                                                     {"md5": "", "file": "bios/keropi/cgrom.dat"}]},

    "x1": {"name": "Sharp X1", "biosFiles": [{"md5": "eeeea1cd29c6e0e8b094790ae969bfa7", "file": "bios/xmil/IPLROM.X1"},
                                             {"md5": "851e4a5936f17d13f8c39a980cf00d77", "file": "bios/xmil/IPLROM.X1T"}]},


    # SNK
    "neogeo":   {"name": "NeoGeo", "biosFiles":    [{"md5": "", "file": "neogeo/neogeo.zip"},
                                                    {"md5": "", "file": "neogeo/aes.zip"}]},

    "neogeocd": {"name": "NeoGeo CD", "biosFiles": [{"md5": "", "file": "neogeo/neogeo.zip"},
                                                    {"md5": "", "file": "bios/neocdz.zip"},
                                                    {"md5": "e255264d85d5765013b1b2fa8109dd53", "file": "bios/neocd/ng-lo.rom"},
                                                    {"md5": "f39572af7584cb5b3f70ae8cc848aba2", "file": "bios/neocd/neocd_z.rom"}]},


    # Sony Computer Entertainment
    "psx": {"name": "PSX", "biosFiles": [{"md5": "8dd7d5296a650fac7319bce665a6a53c", "file": "bios/scph5500.bin"},
                                         {"md5": "490f666e1afb15b7362b406ed1cea246", "file": "bios/scph5501.bin"},
                                         {"md5": "32736f17079d0b2b7024407c39bd3050", "file": "bios/scph5502.bin"}]},


    # Sinclair
    "zxspectrum": {"name": "ZX Spectrum", "biosFiles": [{"md5": "", "file": "bios/128p-0.rom"},
                                                        {"md5": "", "file": "bios/128p-1.rom"},
                                                        {"md5": "", "file": "bios/trdos.rom"},
                                                        {"md5": "", "file": "bios/gluck.rom"},
                                                        {"md5": "", "file": "bios/256s-0.rom"},
                                                        {"md5": "", "file": "bios/256s-1.rom"},
                                                        {"md5": "", "file": "bios/256s-2.rom"},
                                                        {"md5": "", "file": "bios/256s-3.rom"}]},

}

class BiosStatus:
    MISSING = "MISSING"
    UNTESTED = "UNTESTED"

def md5sum(filename, blocksize=65536):
    hash = md5()
    with open(filename, "rb") as f:
        for block in iter(lambda: f.read(blocksize), b""):
            hash.update(block)
    return hash.hexdigest()

def checkInsideZip(container, fileName, md5sum):
    # Check inside Zip files
    try:
        archive = zipfile.ZipFile(container)
    except Exception as e:
        print ('Error opening file {}: {}.'.format(container, e))
        return False
    blocksize = 1024**2  #1M chunks
    for fname in archive.namelist():
        # Only check if the file matches
        if fname.casefold() == fileName.casefold():
            if md5sum == "":
                return True
            archive = zipfile.ZipFile(container)
            blocksize = 1024**2  #1M chunks
            for fname in archive.namelist():
                if fname == fileName:
                    entry = archive.open(fname)
                    zippedHash = md5()
                    while True:
                        block = entry.read(blocksize)
                        if not block:
                            break
                        zippedHash.update(block)
                    if zippedHash.hexdigest() == md5sum:
                        return True
                    else:
                        print('Mismatch inside .zip: File {} in {} has MD5 {} (expected {})'.format(fileName, container, zippedHash.hexdigest(), md5sum))
                        return False
    # File was not found in zip.
    print('Missing file inside .zip: File {} not found in {}'.format(fileName, container))
    return False

def coreExists(checkMe, emuDict):
    if "emulator" in checkMe:
        if checkMe["emulator"] in emuDict.keys():
            hasEmu = True
        else:
            hasEmu = False
    else:
        # Emulator not defined, check BIOS
        hasEmu = True
    if hasEmu and "core" in checkMe:
        if checkMe["core"] in emuDict[checkMe["emulator"]]:
            hasCore = True
        else:
            hasCore = False
    else:
        # Either core is undefined or emulator is not installed.
        # Set core presence to emulator presence, we'll assume there's only one core or it applies to all.
        hasCore = hasEmu
    return hasCore

def checkBios(systems, prefix, filterROMs):
    systemDict = {}
    emuDict = {}
    systemName = ""
    configFile = "/usr/config/emulationstation/es_systems.cfg"
    configData = elementTree.parse(configFile)
    configRoot = configData.getroot()

    if filterROMs:
        # Load systems & emulators from es_systems.cfg
        # System full name stored but not currently used, may be useful for the readme function.
        for activeSystem in configRoot:
            for systemTag in activeSystem:
                if systemTag.tag == "fullname":
                    systemName = systemTag.text
                elif systemTag.tag == "name":
                    systemDict[systemTag.text] = systemName
                    systemName = ""
                elif systemTag.tag == "emulators":
                    for emulatorTag in systemTag:
                        emulatorName = emulatorTag.attrib['name']
                        for coreTag in emulatorTag[0]:
                            if emulatorName in emuDict.keys():
                                if not coreTag.text in emuDict[emulatorName]:
                                    emuDict[emulatorName].append(coreTag.text)
                            else:
                                emuDict[emulatorName] = [coreTag.text]
    else:
        for system in systems.keys():
            systemDict[system] = systems[system]['name']

    missingBios = {}
    for system in systems.keys():
        if system in systemDict.keys():
            if coreExists(systems[system], emuDict) or filterROMs == False:
                for file in systems[system]["biosFiles"]:
                    if coreExists(file, emuDict) or filterROMs == False:
                        filepath = prefix + "/" + file["file"]
                        if isfile(filepath):
                            if not "zippedFile" in file:
                                md5 = md5sum(filepath)
                                if md5 != file["md5"] and file["md5"] != "":
                                    if system not in missingBios:
                                        missingBios[system] = {}
                                    missingBios[system][file["file"]] = { "status": BiosStatus.UNTESTED, "md5": file["md5"], "file": file["file"] }
                            else:
                                if 'altmd5' in file:
                                    if not checkInsideZip(filepath, file["zippedFile"], file["md5"], file["altmd5"]):
                                        if system not in missingBios:
                                            missingBios[system] = {}
                                        missingBios[system][file["file"]] = { "status": BiosStatus.UNTESTED, "md5": file["md5"], "file": file["file"] }
                                else:
                                    if not checkInsideZip(filepath, file["zippedFile"], file["md5"]):
                                        if system not in missingBios:
                                            missingBios[system] = {}
                                        missingBios[system][file["file"]] = { "status": BiosStatus.UNTESTED, "md5": file["md5"], "file": file["file"] }
                        else:
                            if system not in missingBios:
                                missingBios[system] = {}
                            missingBios[system][file["file"]] = { "status": BiosStatus.MISSING, "md5": file["md5"], "file": file["file"] }
    return missingBios

def displayMissingBios(systems, missingBios):
    sortedMissingBios = OrderedDict(sorted(missingBios.items()))
    if sortedMissingBios:
        for system in sortedMissingBios:
            print("> {}".format(system))
            for file in sortedMissingBios[system].keys():
                md5str = "-"
                if sortedMissingBios[system][file]["md5"] != "":
                    md5str = sortedMissingBios[system][file]["md5"]
                print("{} {} {}".format(sortedMissingBios[system][file]["status"], md5str, sortedMissingBios[system][file]["file"]))
    else:
        print("No missing bios")

def createReadme(systems):
    for system in sorted(systems):
        print("{}:".format(systems[system]["name"]))
        for bios in systems[system]["biosFiles"]:
            print("{} {}".format(bios["md5"], bios["file"]))
        print("")

if __name__ == '__main__':
    if len(sys.argv) == 1:
        prefix = "/storage/roms"
        displayMissingBios(systems, checkBios(systems, prefix, True))
    elif sys.argv[1] == "--noFilter":
        prefix = "/storage/roms"
        displayMissingBios(systems, checkBios(systems, prefix, False))
    elif sys.argv[1] == "--createReadme":
        createReadme(systems)
    elif len(sys.argv) == 3 and sys.argv[1] == "--filter":
        prefix = "/storage/roms"
        lowered_name = sys.argv[2].lower()

        filtered_systems = {}
        for system in systems:
            if lowered_name in system.lower() or lowered_name in systems[system]['name'].lower():
                filtered_systems[system] = systems[system]

        if len(filtered_systems) == 0:
            print("No system named {} found".format(sys.argv[2]))
            exit(1)

        displayMissingBios(filtered_systems, checkBios(filtered_systems, prefix, True))
